package com.jd.jobkeeper.client.http;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.util.Map;
import java.util.zip.GZIPInputStream;
import java.util.zip.InflaterInputStream;

import static com.jd.jobkeeper.client.http.HttpRequest.DEFLATE;
import static com.jd.jobkeeper.client.http.HttpRequest.GZIP;
import static java.net.HttpURLConnection.HTTP_NOT_MODIFIED;
import static java.net.HttpURLConnection.HTTP_OK;

public class JdkHttpClient implements HttpClient {

    @Override
    public HttpResponse execute(final HttpRequest request) throws Exception {
        StringBuilder sb = null;
        int status;
        BufferedReader br = null;
        String lastModified = null;
        HttpURLConnection conn = null;
        InputStream inputStream;
        try {
            java.net.URL url = new java.net.URL(request.getUri());
            conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod(request.getHttpMethod());
            conn.setConnectTimeout(request.getConnectTimeout());
            conn.setReadTimeout(request.getSocketTimeout());
            for (Map.Entry<String, String> header : request.getHeaders().entrySet()) {
                conn.setRequestProperty(header.getKey(), header.getValue());
            }
            conn.connect();

            status = conn.getResponseCode();
            if (status == HTTP_NOT_MODIFIED) {
                return new HttpResponse(status, null, lastModified);
            } else if (status == HTTP_OK) {
                inputStream = conn.getInputStream();
                lastModified = conn.getHeaderField(HttpRequest.LAST_MODIFIED);
                //压缩处理
            } else {
                //错误流
                inputStream = conn.getErrorStream();
            }

            if (inputStream != null) {

                String encoding = conn.getContentEncoding();
                if (encoding != null && !encoding.isEmpty()) {
                    if (GZIP.equals(encoding)) {
                        inputStream = new GZIPInputStream(inputStream);
                    } else if (DEFLATE.equals(encoding)) {
                        inputStream = new InflaterInputStream(inputStream);
                    }
                }

                int length = conn.getContentLength();
                sb = new StringBuilder(length <= 0 ? 1024 : length);
                br = new BufferedReader(new InputStreamReader(inputStream, request.charsetName));
                char[] cbuf = new char[1024];
                int len;
                while ((len = br.read(cbuf)) != -1) {
                    sb.append(cbuf, 0, len);
                }
            }
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (Exception e) {

                }
            }

            if (conn != null) {
                conn.disconnect();
            }
        }
        return new HttpResponse(status, sb == null ? "" : sb.toString(), lastModified);
    }
}
